package com.cs157a.view;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Set;

import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

import com.cs157a.controller.AposApplicationController;
import com.cs157a.dao.AplCar;

/**
 * This class shows the filter by auto information tabbed panel.
 * 
 * @author hhong
 * 
 */
public class AutoFilterPanel extends JPanel {

	private static final long serialVersionUID = 20012100301L;

	private AposApplicationController controller;

	private JLabel makeLabel;
	private JLabel modelLabel;
	private JLabel yearLabel;
	private JLabel engineLabel;
	private JLabel descriptionLabel;
	private JLabel litersLabel;
	private JLabel cubicLabel;

	private JComboBox makeComboBox;
	private JComboBox modelComboBox;
	private JComboBox yearComboBox;
	private JComboBox engineComboBox;
	private JComboBox descriptionComboBox;
	private JComboBox litersComboBox;
	private JComboBox cubicComboBox;

	public AutoFilterPanel(AposApplicationController controller) {
		super();
		this.controller = controller;
		controller.setAutoFilterPanel(this);
		init();
	}

	private void init() {
		makeLabel = new JLabel(CommonString.MAKE);
		modelLabel = new JLabel(CommonString.MODEL);
		yearLabel = new JLabel(CommonString.YEAR);
		engineLabel = new JLabel(CommonString.ENGINE);
		descriptionLabel = new JLabel(CommonString.DESCRIPTION);
		litersLabel = new JLabel(CommonString.LITERS);
		cubicLabel = new JLabel(CommonString.CUBIC_INCHES);

		List<String> allMakeNames = controller.getAllMakeNames();
		SortedComboBoxModel makeModel = new SortedComboBoxModel(
				allMakeNames.toArray());
		makeModel.addElement(CommonString.BLANK_SPACE);
		makeComboBox = new JComboBox(makeModel);
		makeComboBox.setSelectedIndex(0);
		makeComboBox.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				// Generate a list of models based on the selected make.
				makeSelectedPerformed();
			}
		});

		modelComboBox = new JComboBox();
		modelComboBox.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				// Generate a list of years based on the selected make and
				// model.
				modelSelectedPerformed();
			}
		});

		yearComboBox = new JComboBox();
		yearComboBox.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				yearSelectedPerformed();
			}
		});

		engineComboBox = new JComboBox();
		engineComboBox.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				engineSelectedPerformed();
			}
		});

		descriptionComboBox = new JComboBox();
		descriptionComboBox.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				descriptionSelectedPerformed();
			}
		});

		litersComboBox = new JComboBox();
		litersComboBox.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				litersSelectedPerformed();
			}
		});

		cubicComboBox = new JComboBox();
		cubicComboBox.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				cubicSelectedPerformed();
			}
		});

		JPanel innerPanel = new JPanel();
		innerPanel.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();

		c.insets = new Insets(5, 5, 5, 5);
		c.anchor = GridBagConstraints.EAST;
		c.fill = GridBagConstraints.HORIZONTAL;
		innerPanel.add(makeLabel, c);

		c.gridx = 0;
		c.gridy = 1;
		innerPanel.add(modelLabel, c);

		c.gridx = 0;
		c.gridy = 2;
		innerPanel.add(yearLabel, c);

		c.gridx = 0;
		c.gridy = 3;
		innerPanel.add(engineLabel, c);

		c.gridx = 0;
		c.gridy = 4;
		innerPanel.add(descriptionLabel, c);

		c.gridx = 0;
		c.gridy = 5;
		innerPanel.add(litersLabel, c);

		c.gridx = 0;
		c.gridy = 6;
		innerPanel.add(cubicLabel, c);

		c.gridx = 1;
		c.gridy = 0;
		innerPanel.add(makeComboBox, c);

		c.gridx = 1;
		c.gridy = 1;
		innerPanel.add(modelComboBox, c);

		c.gridx = 1;
		c.gridy = 2;
		innerPanel.add(yearComboBox, c);

		c.gridx = 1;
		c.gridy = 3;
		innerPanel.add(engineComboBox, c);

		c.gridx = 1;
		c.gridy = 4;
		innerPanel.add(descriptionComboBox, c);

		c.gridx = 1;
		c.gridy = 5;
		innerPanel.add(litersComboBox, c);

		c.gridx = 1;
		c.gridy = 6;
		innerPanel.add(cubicComboBox, c);

		// c.gridx = 0;
		// c.gridy = 7;
		// c.gridwidth = 2;
		// innerPanel.add(autoDetailPanel, c);

		setLayout(new BorderLayout());
		setBorder(new TitledBorder("Filter"));
		add(innerPanel, BorderLayout.NORTH);
	}

	private void cubicSelectedPerformed() {
		// TODO Auto-generated method stub
		String selectedCubic = (String) cubicComboBox.getSelectedItem();
		if (selectedCubic.equals(CommonString.BLANK_SPACE)) {
			return;
		}

		propertySelectedPerformed();

	}

	private void litersSelectedPerformed() {
		// TODO Auto-generated method stub
		String selectedLiter = (String) litersComboBox.getSelectedItem();
		if (selectedLiter.equals(CommonString.BLANK_SPACE)) {
			return;
		}

		propertySelectedPerformed();

	}

	private void descriptionSelectedPerformed() {
		// TODO Auto-generated method stub
		String selectedDesc = (String) descriptionComboBox.getSelectedItem();
		if (selectedDesc.equals(CommonString.BLANK_SPACE)) {
			return;
		}

		propertySelectedPerformed();
	}

	private void propertySelectedPerformed() {
		String selectedMake = (String) makeComboBox.getSelectedItem();
		String selectedModel = (String) modelComboBox.getSelectedItem();
		String selectedYear = (String) yearComboBox.getSelectedItem();
		String selectedEngine = (String) engineComboBox.getSelectedItem();
		String selectedDescription = (String) descriptionComboBox
				.getSelectedItem();
		String selectedLiters = (String) litersComboBox.getSelectedItem();
		String selectedCubic = (String) cubicComboBox.getSelectedItem();

		if (selectedDescription == CommonString.ALL
				|| selectedDescription == CommonString.BLANK_SPACE) {
			selectedDescription = null;
		}
		if (selectedLiters == CommonString.ALL
				|| selectedLiters == CommonString.BLANK_SPACE) {
			selectedLiters = null;
		}
		if (selectedCubic == CommonString.ALL
				|| selectedCubic == CommonString.BLANK_SPACE) {
			selectedCubic = null;
		}

		AplCar selectedCar = new AplCar(selectedModel, selectedYear,
				selectedDescription, selectedLiters, selectedEngine,
				selectedCubic);

		controller.showPartListForAuto(selectedMake, selectedCar);
	}

	private void engineSelectedPerformed() {
		String selectedMake = (String) makeComboBox.getSelectedItem();
		String selectedModel = (String) modelComboBox.getSelectedItem();
		String selectedYear = (String) yearComboBox.getSelectedItem();
		String selectedEngine = (String) engineComboBox.getSelectedItem();

		if (selectedEngine.equals(CommonString.BLANK_SPACE)) {
			return;
		}

		AplCar selectedCar = new AplCar(selectedModel, selectedYear, null,
				null, selectedEngine, null);
		controller.showPartListForAuto(selectedMake, selectedCar);

		// Update description, liters and cubic combos.
		final Set<String> descriptions = controller.getAllDescriptionsForCar(
				selectedMake, selectedCar);

		final Set<String> liters = controller.getAllLitersForCar(selectedMake,
				selectedCar);

		final Set<String> cubics = controller.getAllCubicsForCar(selectedMake,
				selectedCar);

		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				// Update descriptions.
				SortedComboBoxModel descModel = new SortedComboBoxModel(
						descriptions.toArray());

				descModel.addElement(CommonString.BLANK_SPACE);
				if (descriptions.size() > 1) {
					descModel.addElement(CommonString.ALL);
				}
				descriptionComboBox.setModel(descModel);
				descriptionComboBox.setSelectedIndex(0);

				// Update liters.
				SortedComboBoxModel litersModel = new SortedComboBoxModel(
						liters.toArray());
				litersModel.addElement(CommonString.BLANK_SPACE);
				if (liters.size() > 1) {
					litersModel.addElement(CommonString.ALL);
				}

				litersComboBox.setModel(litersModel);
				litersComboBox.setSelectedIndex(0);

				// Update cubics.
				SortedComboBoxModel cubicsModel = new SortedComboBoxModel(
						cubics.toArray());
				cubicsModel.addElement(CommonString.BLANK_SPACE);
				if (cubics.size() > 1) {
					cubicsModel.addElement(CommonString.ALL);
				}

				cubicComboBox.setModel(cubicsModel);
				cubicComboBox.setSelectedIndex(0);
			}
		});

	}

	private void makeSelectedPerformed() {
		String selectedMake = (String) makeComboBox.getSelectedItem();
		if (selectedMake.equals(CommonString.BLANK_SPACE)) {
			return;
		}

		final Set<String> allModelNamesFor = controller
				.getAllModelNamesFor(selectedMake);
		resetModelYearEngineDescLitterCubicCombos();

		// Get some results.
		if (allModelNamesFor.size() > 0) {
			javax.swing.SwingUtilities.invokeLater(new Runnable() {

				@Override
				public void run() {
					SortedComboBoxModel modelModel = new SortedComboBoxModel(
							allModelNamesFor.toArray());
					modelModel.addElement(CommonString.BLANK_SPACE);
					modelComboBox.setModel(modelModel);
					modelComboBox.setSelectedIndex(0);
				}
			});

		} else {
			resetModelYearEngineDescLitterCubicCombos();
		}

	}

	private void modelSelectedPerformed() {
		String selectedMake = (String) makeComboBox.getSelectedItem();
		String selectedModel = (String) modelComboBox.getSelectedItem();
		if (selectedModel.equals(CommonString.BLANK_SPACE)) {
			return;
		}
		resetYearEngineDescLitterCubicCombos();

		final Set<String> allYearsFor = controller.getAllYearsFor(selectedMake,
				selectedModel);

		if (allYearsFor.size() > 0) {
			javax.swing.SwingUtilities.invokeLater(new Runnable() {

				@Override
				public void run() {
					SortedComboBoxModel yearModel = new SortedComboBoxModel(
							allYearsFor.toArray());
					yearModel.addElement(CommonString.BLANK_SPACE);
					yearComboBox.setModel(yearModel);
					yearComboBox.setSelectedIndex(0);
				}
			});

		} else { // Nothing found. Reset the next combo boxes.
			resetYearEngineDescLitterCubicCombos();
		}

	}

	private void yearSelectedPerformed() {
		String selectedMake = (String) makeComboBox.getSelectedItem();
		String selectedModel = (String) modelComboBox.getSelectedItem();
		String selectedYear = (String) yearComboBox.getSelectedItem();
		if (selectedYear.equals(CommonString.BLANK_SPACE)) {
			return;
		}
		resetEngineDescLitterCubicCombos();

		final Set<String> allEnginesFor = controller.getAllEnginesFor(
				selectedMake, selectedModel, selectedYear);

		if (allEnginesFor.size() > 0) {
			javax.swing.SwingUtilities.invokeLater(new Runnable() {

				@Override
				public void run() {
					SortedComboBoxModel engineModel = new SortedComboBoxModel(
							allEnginesFor.toArray());
					engineModel.addElement(CommonString.BLANK_SPACE);
					engineComboBox.setModel(engineModel);
					engineComboBox.setSelectedIndex(0);
				}
			});

		} else { // Nothing found. Reset the combo box(es).
			resetEngineDescLitterCubicCombos();
		}

	}

	private void resetCubicCombos() {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				SortedComboBoxModel emptyModel = new SortedComboBoxModel();
				cubicComboBox.setModel(emptyModel);
			}
		});
	}

	private void resetLitterCubicCombos() {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				SortedComboBoxModel emptyModel = new SortedComboBoxModel();
				litersComboBox.setModel(emptyModel);
			}
		});
		resetCubicCombos();
	}

	private void resetDescLitterCubicCombos() {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				SortedComboBoxModel emptyModel = new SortedComboBoxModel();
				descriptionComboBox.setModel(emptyModel);
			}
		});
		resetLitterCubicCombos();
	}

	private void resetEngineDescLitterCubicCombos() {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				SortedComboBoxModel emptyModel = new SortedComboBoxModel();
				engineComboBox.setModel(emptyModel);
			}
		});

		resetDescLitterCubicCombos();
	}

	private void resetYearEngineDescLitterCubicCombos() {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				SortedComboBoxModel emptyModel = new SortedComboBoxModel();
				yearComboBox.setModel(emptyModel);
			}
		});

		resetEngineDescLitterCubicCombos();
	}

	private void resetModelYearEngineDescLitterCubicCombos() {

		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				SortedComboBoxModel emptyModel = new SortedComboBoxModel();
				modelComboBox.setModel(emptyModel);
			}
		});

		resetYearEngineDescLitterCubicCombos();
	}

	public void setMakes(List<String> allMakeNames) {
                
		SortedComboBoxModel makeModel = new SortedComboBoxModel(
				allMakeNames.toArray());
		makeModel.addElement(CommonString.BLANK_SPACE);
		makeComboBox.setModel(makeModel);
		makeComboBox.setSelectedIndex(0);
                resetModelYearEngineDescLitterCubicCombos();
	}
        
}
